package core

import (
	"fmt"
	"io"
	"net"
	"time"
)

const (
	TCP_STATE_CONNECTED = iota
	TCP_STATE_DISCONNECTED
	TCP_STATE_DATA
	TCP_STATE_ERROR
)

type TcpServer struct {
	Port int
	Call func(ref interface{}, conn net.Conn, state int, err error, data []byte, datasize uint32)
	Ref  interface{}
}

func NewTcpServer(port int, call func(ref interface{}, conn net.Conn, state int, err error, data []byte, datasize uint32), ref interface{}) *TcpServer {
	return &TcpServer{
		Port: port,
		Call: call,
		Ref:  ref,
	}
}
func (s *TcpServer) Start() error {
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Port))
	if err != nil {
		return err
	}

	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				s.Call(s.Ref, conn, TCP_STATE_ERROR, err, nil, 0)
				continue
			}
			go s.handleConnection(conn)
		}
	}()
	return nil
}

func (s *TcpServer) handleConnection(conn net.Conn) {
	GetCount().ClientCount++
	defer conn.Close()
	s.Call(s.Ref, conn, TCP_STATE_CONNECTED, nil, nil, 0)
	if tcpConn, ok := conn.(*net.TCPConn); ok {
		tcpConn.SetNoDelay(true)
		tcpConn.SetReadBuffer(1024 * 32)
		tcpConn.SetWriteBuffer(1024 * 32)            //视频流媒体服务 256K,IM 32K(保持10万并发)
		tcpConn.SetKeepAlive(true)                   // 保持长连接活跃
		tcpConn.SetKeepAlivePeriod(10 * time.Minute) // 减少保活探测频率
	}

	for {
		data, err := ReadBytes(conn)

		if err != nil {
			if err == io.EOF {
				s.Call(s.Ref, conn, TCP_STATE_DISCONNECTED, err, data, 0)
			} else {
				s.Call(s.Ref, conn, TCP_STATE_ERROR, err, data, 0)
			}
			break
		}
		ss := len(data)

		GetCount().PackageCount++
		GetCount().PackageSize += uint64(ss) + 4

		s.Call(s.Ref, conn, TCP_STATE_DATA, nil, data, uint32(ss))
	}
	GetCount().ClientCount--
}
